package com.alan.libapi.api.Impl;

import android.util.Log;

import com.alan.libapi.utils.ByteUtil;
import com.alan.library.allog.KLog;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.util.Arrays;

/**
 * @className: PackageHelper
 * @describtion: PackageHelper
 * @author: AlanWang
 * @email: 850267876@qq.com
 * @time: 2016/4/28 09:52
 */
public class PackageHelper {

    private byte[] readBuf = new byte[1024];
    private byte[] readHeaderBytes = new byte[PackageHeader.HEADER_LENGTH];

    public PackageHelper() {
    }

    /**
     * 打包原数据，从而可以通过socket发送
     * @param srcData 为打包的数据
     * @return
     */
    private byte[] packData(byte[] srcData) {
        int length = srcData.length;
        byte[] headerBytes = PackageHeader.getHeaderBytes(length);
        return ByteUtil.byteMerger(headerBytes, srcData);
    }

    /**
     * 写数据到 synchronized
     * @param data 不包含头信息的数据
     * @return
     * @throws IOException
     */
    public boolean request(OutputStream os, byte[] data) throws IOException {
        //sendData = packData(data);
        //KLog.d(Arrays.toString(data));
        byte[] sendData = packData(data);
//        KLog.d("data.len = " +data.length + "&&&&&data = " +  ByteUtil.byte2hex(sendData));
//		Log.i("aaa", "" + new String(datas));
        os.write(sendData);
        os.flush();
        return true;
    }

    /**
     * 读取响应数据 synchronized
     * @return
     * @throws Exception
     */
    public byte[] response(InputStream is) throws SocketTimeoutException,Exception {
        int len = 0,total = 0;
        int headerBytesOffset = 0;
        int contentLength = -1;
        int headerLength=0;
        int tempLen = 0;
        byte[] contentBytes = null;
        int contentBytesOffset = 0;
        try {
            do {
                //KLog.d("readBuf.len = " +readBuf.length + "&&&&&data = " +  ByteUtil.byte2hex(readBuf));
                total += len;
                headerBytesOffset = 0;
                tempLen = 0;
                if(headerLength < PackageHeader.HEADER_LENGTH) {
                    if((headerLength + len) > PackageHeader.HEADER_LENGTH) {
                        tempLen = PackageHeader.HEADER_LENGTH - headerLength;
                    } else {
                        tempLen = len;
                    }
                    System.arraycopy(readBuf, 0, readHeaderBytes, headerLength, tempLen);

                    headerLength += tempLen;
                    headerBytesOffset = tempLen;
                }

                if((contentLength < 0) && (headerLength >= PackageHeader.HEADER_LENGTH)) {
                    //读取头信息已经完成，可以获取内容主体长度信息
                    contentLength = PackageHeader.getContentLength(readHeaderBytes);
                    contentBytes = new byte[contentLength];
                }

                //减去获取的头信息部分的长度
                len = len - headerBytesOffset;
                KLog.d( "len = " + len);
                if((contentBytes != null) && (len > 0)) {
                    if((len + contentBytesOffset) > contentLength) {
                        //发现有超出的数据部分，需要保留下来，留给下次读取数据使用
                        tempLen = contentLength - contentBytesOffset;
                        KLog.d("contentLength = " + contentLength);
                        KLog.d("contentBytesOffset = " + contentBytesOffset);
                        KLog.d("tempLen = " + tempLen);
                        for(int i = 0 ;  i < len; i++) {
                            Log.d(this.getClass().getSimpleName(), "readBuf["+ i + "] = " + readBuf[i]);
                        }
                    } else {
                        tempLen = len;
                    }
                    System.arraycopy(readBuf, headerBytesOffset, contentBytes, contentBytesOffset, tempLen);
                    contentBytesOffset += tempLen;
                }
                if(total >= (contentLength + PackageHeader.HEADER_LENGTH) ) {
                    //读取完成一个返回结果&&&&&
                    break;
                }
                len = 0;
                if(contentBytes != null){
                    KLog.d(""+ new String(contentBytes));
                }
            }while((len = is.read(readBuf, 0, readBuf.length)) > -1);
        } catch (SocketTimeoutException e) {
            // TODO Auto-generated catch block
            Log.i("NasSocketHelper", "while  read>>>>"+e.toString());
            //e.printStackTrace();
            throw e;
        }
        KLog.d("socke read len = " + len);
        return contentBytes;
    }

}
